package etc.domain;


import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.dmz.test.etc.utils.Convert;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.io.UnsupportedEncodingException;

import static java.lang.Math.round;


/**
 * @author lee
 */
@Setter
@Getter
@Slf4j
public class MsgHeader implements java.io.Serializable {
    /**
     *
     */
    private final String encoding = "GBK";
    private final String padStr = "0";
    private static final long serialVersionUID = 1L;
    private String messageLength;
    private String receiverId;
    private String senderId;
    private String messageType;
    private String messageId;
    private String verifyCode;

    @Override
    public String toString() {
        return messageLength + receiverId + senderId +
                messageType +
                messageId +
                verifyCode;
    }

    public void analyze(byte[] headBytes) {
        log.info("5.1解析报文头===============================");
        log.info("原始报文头:{}", headBytes);
        byte[] totalLen = new byte[4];
        System.arraycopy(headBytes, 0, totalLen, 0, 4);
        setMessageLength(StrUtil.padPre(Integer.toString(Convert.bytes2Int(totalLen)), 4, padStr));
        byte[] receiverId = new byte[7];
        System.arraycopy(headBytes, 4, receiverId, 0, 7);
        setReceiverId(StrUtil.str(receiverId, encoding));
        byte[] senderId = new byte[7];
        System.arraycopy(headBytes, 11, senderId, 0, 7);
        setSenderId(StrUtil.str(senderId, encoding));
        byte[] msgType = new byte[4];
        System.arraycopy(headBytes, 18, msgType, 0, 4);
        setMessageType(StrUtil.str(msgType, encoding));
        byte[] msgId = new byte[4];
        System.arraycopy(headBytes, 22, msgId, 0, 4);
        setMessageId(StrUtil.padPre(Integer.toString(Convert.bytes2Int(msgId)), 4, padStr));
        byte[] verifyCode = new byte[32];
        System.arraycopy(headBytes, 26, verifyCode, 0, 32);
        setVerifyCode(StrUtil.str(verifyCode, encoding));

        log.info("5.2报文头解析完毕==============================");
        log.info("解析后报文头内容:{}", this);
    }

    public void forward(byte[] headBytes) throws UnsupportedEncodingException {
        //log.info("received--message--head--str:{}", headBytes);
        byte[] totalLen = new byte[4];
        System.arraycopy(headBytes, 0, totalLen, 0, 4);
        setMessageLength(new String(totalLen, encoding));
        byte[] receiverId = new byte[7];
        System.arraycopy(headBytes, 4, receiverId, 0, 7);
        setReceiverId(new String(receiverId, encoding));
        byte[] senderId = new byte[7];
        System.arraycopy(headBytes, 11, senderId, 0, 7);
        setSenderId(new String(senderId, encoding));
        byte[] msgType = new byte[4];
        System.arraycopy(headBytes, 18, msgType, 0, 4);
        setMessageType(StrUtil.str(msgType, encoding));
        byte[] msgId = new byte[4];
        System.arraycopy(headBytes, 22, msgId, 0, 4);
        setMessageId(new String(msgId, encoding));
        byte[] verifyCode = new byte[32];
        System.arraycopy(headBytes, 26, verifyCode, 0, 32);
        setVerifyCode(StrUtil.str(verifyCode, encoding));
    }

    public byte[] headSet(String reqBody) {

        // MD5加密
        verifyCode = SecureUtil.md5(reqBody);
        //todo
        int totalLen = 58 + (round((reqBody.length() >> 3) + 1) << 3);
        byte[] head = new byte[58];
        byte[] head1 = Convert.int2Bytes(totalLen);
        byte[] head2 = (getSenderId() + getReceiverId() + getMessageType()).getBytes();
        byte[] head3 = Convert.int2Bytes(Integer.parseInt(getMessageId()) + 1);
        byte[] head4 = verifyCode.getBytes();
        System.arraycopy(head1, 0, head, 0, head1.length);
        System.arraycopy(head2, 0, head, head1.length, head2.length);
        System.arraycopy(head3, 0, head, head1.length + head2.length,
                head3.length);
        System.arraycopy(head4, 0, head, head1.length + head2.length
                + head3.length, head4.length);
        //analyze(head);
        //log.info("server--send--head:{}", this);
        //log.info("server--send--head--bytes:{}", head);
        return head;
    }
}
